﻿using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SubtitleFineTuning {
    public partial class FrmSubtitleAss : Form {
        private string m_DropFilePath;
        private TargetEnCoding targetEncoding;

        public FrmSubtitleAss() {
            InitializeComponent();
        }

        /// <summary>
        /// 窗体载入
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e) {
            txtOffsetTime.Text = "0:00:00.00";
            btnToFile.Enabled = false;
            RefreshView();
        }

        /// <summary>
        /// 执行按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnExecute_Click(object sender, EventArgs e) {
            txtNew.Text = Subtitle(txtOrigin.Text);
        }

        /// <summary>
        /// 仅调整选择的部分
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnExecuteSelected_Click(object sender, EventArgs e) {
            string text = txtOrigin.Text;
            string left = text.Substring(0, txtOrigin.SelectionStart);
            string right = text.Substring(txtOrigin.SelectionStart + txtOrigin.SelectionLength);
            string selectdText = txtOrigin.SelectedText;

            StringBuilder sb = new StringBuilder();
            sb.Append(left);
            sb.Append(Subtitle(selectdText));
            sb.Append(right);
            txtNew.Text = sb.ToString();
            sb.Clear();
        }

        /// <summary>
        /// 调整其他
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnExecuteOther_Click(object sender, EventArgs e) {
            string filePath = m_DropFilePath;
            if (string.IsNullOrEmpty(filePath)) {
                MessageBox.Show("路径不存在，只适合拖拽后使用哦", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            } else {
                if(DialogResult.Yes == MessageBox.Show("即将调整其他未拓展的字幕文件。\n\n而且将直接写入文件，确定执行？", "询问", MessageBoxButtons.YesNo, MessageBoxIcon.Information)) {
                    string directory = Path.GetDirectoryName(m_DropFilePath);
                    string fileExtName = Path.GetExtension(filePath);
                    string [] files = Directory.GetFiles(directory);
                    int count = 0;
                    for(int i = 0; i < files.Length; i++) {
                        string file = files[i];
                        if(fileExtName.Equals(Path.GetExtension(file), StringComparison.OrdinalIgnoreCase)) {//如果也是字幕文件
                            if (!file.Equals(filePath, StringComparison.OrdinalIgnoreCase)) {//如果不是拖拽进来的文件
                                String allLine = File.ReadAllText(file);
                                allLine = Subtitle(allLine);
                                switch (targetEncoding){
                                    case TargetEnCoding.NONE:
                                        break;
                                    case TargetEnCoding.SC:
                                        allLine = ConvSimplified(allLine);
                                        break;
                                    case TargetEnCoding.TC:
                                        allLine = ConvTraditional(allLine);
                                        break;

                                }
                                File.WriteAllText(file, allLine);
                                count++;
                            }
                        }
                    }
                    MessageBox.Show(string.Format("调整完毕，调整了{0}个文件", count), "完成", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }
        }

        private string Subtitle(string assFileAllLine) {
            String format = @"h\:mm\:ss\.FF";
            TimeSpan offsetTime = TimeSpan.Parse(txtOffsetTime.Text);
            //Console.WriteLine("offsetTime == " + offsetTime.ToString(format));
            String[] lines = assFileAllLine.Split(new String[] { "\r\n", "\n" }, StringSplitOptions.None);

            StringBuilder sb = new StringBuilder();
            foreach (String line in lines) {
                //Console.WriteLine(line);
                if (line.Contains("Dialogue:")) {
                    sb.Append(FormatTimeLine(line, "Dialogue:", offsetTime, format));
                } else if (line.Contains("Comment:")) {
                    sb.Append(FormatTimeLine(line, "Comment:", offsetTime, format));
                } else {
                    sb.Append(line);
                }
                sb.Append("\r\n");
            }
            string result = sb.ToString();
            sb.Length = 0;
            return result;
        }

        /// <summary>
        /// 按钮 - 复制到剪切板
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnToClipboard_Click(object sender, EventArgs e) {
            Clipboard.Clear();
            if(txtNew.TextLength > 0) {
                Clipboard.SetText(txtNew.Text);
            }
            MessageBox.Show("成功复制到剪切板！", "完成", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        /// <summary>
        /// 按钮 - 写入到文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnToFile_Click(object sender, EventArgs e) {
            string filePath = m_DropFilePath;
            if (string.IsNullOrEmpty(filePath)) {
                MessageBox.Show("路径不存在，只适合拖拽后使用哦", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            } else {
                StringBuilder sb = new StringBuilder();
                sb.Append("您将内容写入到下面这个文件吗？");
                sb.Append("\r\n");
                sb.Append(Path.GetFileName(filePath));
                sb.Append("\r\n");
                sb.Append("完整路径：").Append(filePath);
                string text = sb.ToString();
                sb.Clear();
                if (DialogResult.OK == MessageBox.Show(text, "写入文件？", MessageBoxButtons.OKCancel, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1)) {
                    File.WriteAllText(filePath, txtNew.Text);
                }
            }
        }

        /// <summary>
        /// 格式化时间行
        /// </summary>
        /// <param name="line"></param>
        /// <param name="key"></param>
        /// <param name="offsetTime"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        private string FormatTimeLine(String line, String key, TimeSpan offsetTime, string format) {
            String parameStr = line.Substring(key.Length);
            string[] parames = parameStr.Split(new String[] { "," }, StringSplitOptions.None);
            string startTimeStr = parames[1];
            string endTimeStr = parames[2];

            TimeSpan startTime = TimeSpan.Parse(FormatTime(startTimeStr));
            TimeSpan endTime = TimeSpan.Parse(FormatTime(endTimeStr));

            startTime += offsetTime;
            endTime += offsetTime;

            string newStartTimeStr = FormatTime(startTime.ToString(format));
            string newEndTimeStr = FormatTime(endTime.ToString(format));
            

            String newLine = line.Replace(startTimeStr, newStartTimeStr);
            newLine = newLine.Replace(endTimeStr, newEndTimeStr);
            return newLine;
        }

        /// <summary>
        /// 格式化时间字符串
        /// </summary>
        /// <param name="timeStr"></param>
        /// <returns></returns>
        private string FormatTime(string timeStr) {
            int lastIndexDot = timeStr.LastIndexOf(".");
            int appendZeroCount = 2 - (timeStr.Length - lastIndexDot) + 1;
            if(appendZeroCount < 0) {
                int subLength = timeStr.Length + appendZeroCount;// appendZeroCount 是负数， 加负数等于扣除
                if (subLength > -1 && subLength < timeStr.Length) {
                    timeStr = timeStr.Substring(0, subLength);
                }
            }else {
                for(int i = 0; i < appendZeroCount; i++) {
                    timeStr += "0";
                }
            }
            return timeStr;
        }

        /// <summary>
        /// 原始字幕内容控件里的内容发生变更
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtOrigin_TextChanged(object sender, EventArgs e) {
            btnToFile.Enabled = false;
        }

        /// <summary>
        /// 原始字幕内容控件键盘按下
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TxtOrigin_KeyDown(object sender, KeyEventArgs e) {
            TextBox_KeyDown(txtOrigin, e);
        }

        /// <summary>
        /// 新字幕内容控件键盘按下
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TxtNew_KeyDown(object sender, KeyEventArgs e) {
            TextBox_KeyDown(txtNew, e);
        }

        /// <summary>
        /// 控件键盘按下事件
        /// </summary>
        /// <param name="textBox"></param>
        /// <param name="e"></param>
        private void TextBox_KeyDown(TextBox textBox, KeyEventArgs e) {
            if (e.Control && e.KeyCode == Keys.A) {
                textBox.SelectionStart = 0;
                textBox.SelectionLength = textBox.TextLength;
            }
        }

        /// <summary>
        /// 原始字幕内容控件拖拽进入
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtOrigin_DragEnter(object sender, DragEventArgs e) {
            if (e.Data.GetDataPresent(DataFormats.FileDrop)) {
                e.Effect = DragDropEffects.All; //重要代码：表明是所有类型的数据，比如文件路径
            }else {
                e.Effect = DragDropEffects.None;
            }
        }
        /// <summary>
        /// 原始字幕内容控件拖拽完成
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtOrigin_DragDrop(object sender, DragEventArgs e) {
            Array array = (System.Array)e.Data.GetData(DataFormats.FileDrop);
            if(array.Length > 0) {
                Object obj = array.GetValue(0);
                if(obj != null) {
                    string path = obj.ToString();       //获得路径
                    if (File.Exists(path)) {
                        txtOrigin.Text = File.ReadAllText(path);
                        m_DropFilePath = path;
                        btnToFile.Enabled = true;
                        targetEncoding = TargetEnCoding.NONE;
                    }
                }

            }
        }

        /// <summary>
        /// 转换为简体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtSimplified_Click(object sender, EventArgs e) {
            if(txtNew.TextLength > 0) {
                targetEncoding = TargetEnCoding.SC;
                txtNew.Text = ConvSimplified(txtNew.Text);
            }
        }

        /// <summary>
        /// 转换为繁体
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtTraditional_Click(object sender, EventArgs e) {
            if (txtNew.TextLength > 0) {
                targetEncoding = TargetEnCoding.TC;
                txtNew.Text = ConvTraditional(txtNew.Text);
            }
        }

        /// <summary>
        /// 转换为简体
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private string ConvSimplified(string str){
            return Microsoft.VisualBasic.Strings.StrConv(str, Microsoft.VisualBasic.VbStrConv.SimplifiedChinese);
        }

        /// <summary>
        /// 转换为繁体
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private string ConvTraditional(string str){
            return Microsoft.VisualBasic.Strings.StrConv(str, Microsoft.VisualBasic.VbStrConv.TraditionalChinese);
        }
        private int defaultPadding = 15;

        private void FrmSubtitleAss_SizeChanged(object sender, EventArgs e) {
            RefreshView();
        }

        private Point m_LastMousePositin;
        private Point m_Offset;
        private bool m_Donwing;
        private void panelCenter_MouseDown(object sender, MouseEventArgs e) {
            m_LastMousePositin = new Point();
            m_Donwing = true;
        }

        private void panelCenter_MouseMove(object sender, MouseEventArgs e) {
            if (m_Donwing) {
                //确定目标坐标点
                m_Offset.X = m_LastMousePositin.X += e.X;
                RefreshView();
            }
        }
        private void panelCenter_MouseUp(object sender, MouseEventArgs e) {
            m_Donwing = false;
        }

        private void RefreshView() {
            //左边
            txtOrigin.Left = defaultPadding;
            lblTitleOrigin.Left = txtOrigin.Left;
            txtOrigin.Width = (this.Size.Width - defaultPadding * 4) / 2 + m_Offset.X;
            txtOrigin.Height = this.Size.Height - txtOrigin.Top - 50;

            //右边
            int rightStartX = txtOrigin.Right + defaultPadding * 2;
            txtNew.Left = rightStartX;
            lblTitleNew.Left = txtNew.Left;
            txtNew.Width = this.Size.Width - txtNew.Left - 15 - defaultPadding;
            txtNew.Height = txtOrigin.Height;

            //右上角面板
            panelRightTop.Left = txtNew.Right - panelRightTop.Width;

            //中间面板
            panelCenter.Left = (txtOrigin.Right + txtNew.Left) / 2 - panelCenter.Width / 2;
            panelCenter.Height = txtOrigin.Height;
        }

    }
    
}
